package educational.cad.model;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;

/**
 * This class represents the main educational cad entity.
 * 
 * @author Seroshtan Sergey
 * 
 */
public final class Board {

	/**
	 * <<packages>>
	 */

	/**
	 * This method returns packages placed on the board.
	 */
	public Collection<Package> packages() {
		final ArrayList<Package> packages = new ArrayList<Package>(packagesPosition.keySet());
		return packages;
	}

	/**
	 * This method returns the position of the specified package on the board.
	 */
	public Position positionOf(Package pack) {
		return packagesPosition.get(pack);

	}

	/**
	 * This method returns unique tag of the specified package.
	 */
	public String tagOf(Package pack) {
		return null;
	}

	/**
	 * <<wires>>
	 */

	/**
	 * This method returns all wires located on the board.
	 */
	public Collection<Wire> wires() {
		final ArrayList<Wire> wires = new ArrayList<Wire>(wiresPath.keySet());
		return wires;
	}

	/**
	 * This method returns the path of the specified wire. -
	 */
	public WirePath pathOf(Wire wire) {
		return wiresPath.get(wire);
	}

	/**
	 * This method returns unique tag of the specified wire.
	 */
	public String tagOf(Wire wire) {
		return null;
	}

	/**
	 * <<properties>>
	 */

	public Board(int width, int height, HashMap<Package, Position> packagesPosition, HashMap<Wire, WirePath> wiresPath) {
		if (width < 0) {
			throw new IllegalArgumentException("Board width is negative.");
		}
		if (height < 0) {
			throw new IllegalArgumentException("Board height is negative.");
		}
		this.width = width;
		this.height = height;

		if (packagesPosition == null) {
			throw new IllegalArgumentException("Packages with their positions was not specified.");
		}
		if (wiresPath == null) {
			throw new IllegalArgumentException("Wires whith their pathes was not specified.");
		}
		this.packagesPosition = packagesPosition;
		this.wiresPath = wiresPath;
		this.wiresTag = new HashMap<Wire, String>();
		this.packagesTag = new HashMap<Package, String>();
		
		generatePackagesTag();
		generateWiresTag();
	}

	/**
	 * This method returns the board width in the abstract units.
	 */
	public int width() {
		return width;
	}

	/**
	 * This method returns the board height in the abstract units.
	 */
	public int height() {
		return height;
	}

	private void generatePackagesTag() {
		final String tag = "p";
		int freeTagNum = 0;
		for (Package pack : packages()) {
			packagesTag.put(pack, tag + freeTagNum);
			++freeTagNum;
		}
	}

	private void generateWiresTag() {
		final String tag = "n";
		int freeTagNum = 0;
		for (Wire wire : wires()) {
			wiresTag.put(wire, tag + freeTagNum);
			++freeTagNum;
		}
	}

	private final int width;
	private final int height;
	private final HashMap<Package, Position> packagesPosition;
	private final HashMap<Wire, WirePath> wiresPath;
	private final HashMap<Package, String> packagesTag;
	private final HashMap<Wire, String> wiresTag;

}
